package emulator.shell.GUI.profiling;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.tree.TreePath;

import emulator.GUI.PersistentFrame;

@SuppressWarnings("serial")
public class ProfilingStatisticsView extends PersistentFrame
{
	private ProfilingStatisticsPresenter presenter;
	private ProfilingStatisticsVM viewModel;
	private JTable codeTable;
	private JTable callTable;
	private JTree callTree;

	public ProfilingStatisticsView(String appName, ProfilingStatisticsPresenter presenter)
	{
		super("Profiling", appName);
		this.presenter = presenter;
	}
	
	public void initView(ProfilingStatisticsVM viewModel)
	{
		this.viewModel = viewModel;
		
		codeTable = new JTable();
		codeTable.setAutoCreateRowSorter(true);
		codeTable.setModel(viewModel.getCodeTableModel());
		codeTable.addMouseListener(new CodeTableListener());

		callTable = new JTable();
		callTable.setAutoCreateRowSorter(true);
		callTable.setModel(viewModel.getCallTableModel());
		callTable.addMouseListener(new callTableListener());
		
		callTree = new JTree(viewModel.getCallTreeModel());
		callTree.addMouseListener(new CallTreeListener());
		callTree.setToggleClickCount(5);
		
		JScrollPane codeList = new JScrollPane(codeTable);
		JScrollPane callList = new JScrollPane(callTable);
		JScrollPane graphList = new JScrollPane(callTree);
		
		JTabbedPane tabbedPane = new JTabbedPane();
		tabbedPane.addTab("Code", codeList);
		tabbedPane.addTab("Calls", callList);
		tabbedPane.addTab("Tree", graphList);
		
		JButton button = new JButton("Reset & Close");
		button.addActionListener(new ResetAndClose());
		button.setAlignmentX(Component.CENTER_ALIGNMENT);
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
		buttonPanel.add(Box.createVerticalGlue());
		buttonPanel.add(button);
		buttonPanel.add(Box.createVerticalGlue());
		
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(tabbedPane, BorderLayout.CENTER);
		getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
	}

	@Override
	public void windowClosing(WindowEvent arg0)
	{
		super.windowClosing(arg0);
		presenter.onCloseView();
	}
	
	public class CodeTableListener extends MouseAdapter
	{
		@Override
		public void mousePressed(MouseEvent e)
		{
			if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2)
			{
				int rowIndex = codeTable.rowAtPoint(e.getPoint());
				int modelRow = codeTable.convertRowIndexToModel(rowIndex);
				presenter.showCode(viewModel.getAddressAtCodeLine(modelRow));
			}
		}
	}

	public class callTableListener extends MouseAdapter
	{
		@Override
		public void mousePressed(MouseEvent e)
		{
			if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2)
			{
				int rowIndex = callTable.rowAtPoint(e.getPoint());
				int modelRow = callTable.convertRowIndexToModel(rowIndex);
				presenter.showCode(viewModel.getAddressAtCall(modelRow));
			}
		}
	}
	
	public class CallTreeListener extends MouseAdapter
	{
		@Override
		public void mousePressed(MouseEvent e)
		{
			if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2)
			{
				TreePath clickedPath = callTree.getPathForLocation(e.getX(), e.getY());
				if (clickedPath != null)
				{
					CallTreeModelData node = (CallTreeModelData)clickedPath.getLastPathComponent();
					if (node.getAddress() >= 0)
						presenter.showCode(node.getAddress());
				}
			}
		}
	}

	public class ResetAndClose implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e)
		{
			presenter.resetStatisticsAndCloseView();
		}
	}
}
